package com.choupin.choupin.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.choupin.choupin.entity.Member;
import com.choupin.choupin.entity.Mine;
import com.choupin.choupin.entity.User;
import com.choupin.choupin.interceptor.MyLoginInterceptor;
import com.choupin.choupin.mapper.MemberMapper;
import com.choupin.choupin.mapper.UserMapper;
import com.choupin.choupin.service.IUserService;
import com.choupin.choupin.service.exception.*;
import com.choupin.choupin.utils.MD5AndSalt;
import com.choupin.choupin.utils.images.ImagesUtils;
import com.choupin.choupin.utils.redis.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpSession;
import javax.xml.crypto.Data;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.web.multipart.MultipartFile;

@SuppressWarnings("ALL")
@Service
public class UserServiceImpl implements IUserService {
    private static final  Integer AVATAR_MAX_SIZE=600*1024;
    private  static final List<String> AVATARTYPE=new ArrayList<>();
    private  static final  String LOCAL_UPLOAD_PATH="D:/choupin/src/main/resources/static/upload/avatar/";
    private  static final  String LOCAL_FRONT_PATH="D:/uniapp/choupinSaveImage/static/avatar/user/";
    static {
        AVATARTYPE.add("image/jpeg");
        AVATARTYPE.add("image/png");
        AVATARTYPE.add("image/jpg");
    }

    @Autowired
    UserMapper userMapper;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    MyLoginInterceptor loginInterceptor;

    @Autowired
    MemberMapper memberMapper;

    private String verificationCode;


    // 注册
    @Override
    public void register(User user) {
        //先通过账号，查询数据库是否注册过改用户，
         String phone=user.getPhone();
         User u=userMapper.selectPhone(phone);
         if (u!=null){
             // 如果是则直接返回提示“账号已注占用”
         throw  new SelectExcepion("账号已注占用！");
         }
        //否则，对账号进行注册
        //生成一个随即昵称
        Random random=new Random();
        user.setNickname("用户"+random.nextInt(1000));

        user.setCreatedUser(user.getPhone());
         user.setModifiedUser(user.getPhone());

         LocalDateTime now=LocalDateTime.now();
        DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowdateString=now.format(formatter);
        LocalDateTime localDateTime=LocalDateTime.parse(nowdateString,formatter);
        user.setCreatedTime(localDateTime);
        user.setModifiedTime(localDateTime);
        //加密密码
         String salt= UUID.randomUUID().toString().toUpperCase();
         user.setSalt(salt);
         String password= MD5AndSalt.getMD5Password(user.getPassword(),salt);
         user.setPassword(password);
//         计算年龄
        Date nowTime= new Date();
        Instant instant1=user.getBirthday().toInstant();
        Instant instant2=nowTime.toInstant();
        Duration duration=Duration.between(instant1,instant2);
        if (duration.toDays()/365<1){
            user.setAge(1);
        }else {
            user.setAge((int) (duration.toDays()/365));
        }
//         设置默认头像
        user.setAvatar("/static/avatar/default/defaultuser.png");
//        设置账号状态
         user.setIsDelete(0);
//         设置会员默认状态
        user.setIsVip(0);
//        设置中奖概率默认值
        user.setWeight(10);
//        初始化用户中奖次数
        user.setCount(0);
        userMapper.insertUser(user);
    }

//     密码登录
    @Override
    public void pwdlogin(String phone, String password,HttpSession session) {
        //先判断这个账号注册没有
        User user=userMapper.selectPhone(phone);
        if (user==null){
            throw  new SelectExcepion("账号没有注册，请先注册账号！");
        }
//        判断封号


        //比较密码
        password=MD5AndSalt.getMD5Password(password,user.getSalt());
        if(password.equals(user.getPassword())){
//        存入redis缓存中，用于后续登录判断
        redisUtils.addRedis("phone:"+phone,phone);
        redisUtils.addRedis("password:"+phone,password);
//        获取当前时间
            String time=LocalDateTime.now().toString();
//        将当前登录的时间存入，redis中用于登录失效判断
        redisUtils.addRedis("time:"+phone,time);
            System.out.println("已经将电话号码存入redis中！");
            System.out.println("从session中取出："+session.getAttribute("phone"));
            System.out.println("从redis中取出："+redisUtils.getValue("phone:"+phone));
        }else {
            throw new PasswordException("密码错误！");
        }
    }

//    发送短信验证码
    @Override
    public String sendmessage(String phone) {
//        先判断手机号是否注册
        User user=userMapper.selectPhone(phone);
        if (user==null){
            throw new SelectExcepion("手机号未注册，请先注册！");
        }

        // 替换为你的AccessKey ID和AccessKey Secret
        String accessKeyId = "LTAI5tR1ZWM97c7pGXcpubrm";
        String accessKeySecret = "Te5711p4ILW7ofU0G2opT40w9gXaq1";

        // 替换为你的短信签名和模板CODE
        String signName = "抽品";
        String templateCode = "SMS_463623423";

        // 替换为接收短信的手机号码和登录验证码
        String phoneNumber =phone;
        verificationCode =generateVerificationCode();


        // 初始化短信客户端
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com");
        IAcsClient client = new DefaultAcsClient(profile);

        // 创建发送短信请求对象
        SendSmsRequest request = new SendSmsRequest();
        request.setPhoneNumbers(phoneNumber);
        request.setSignName(signName);
        request.setTemplateCode(templateCode);
        request.setTemplateParam("{\"code\":\"" + verificationCode + "\"}");

        // 发送短信并获取响应
        SendSmsResponse sendSmsResponse = null;
        try {
            sendSmsResponse = client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        System.out.println("短信发送结果：" + sendSmsResponse.getCode());
        return verificationCode;
    }

    //    生成一个六位数的验证码用于发送给手机
    public static String generateVerificationCode() {
        Random random = new Random();
        int code = random.nextInt(900000) + 100000;
        return String.valueOf(code);
    }

//短信验证登陆
    @Override
    public void messagelogin(String code,String phone) {

//        短信登录验证
        if (!verificationCode.equals(code)){
            throw new CaptchaException("验证码错误！");
        }
        //        存入redis缓存中，用于后续登录判断
        redisUtils.addRedis("phone:"+phone,phone);

    }

//    登录拦截方法
    @Override
    public void loginInterceptor(String phone) {
        Boolean result=loginInterceptor.LoginInterceptor(phone,"phone:"+phone,"time:"+phone);
        System.out.println("result是个什么情况："+result);
        if (result==false){
            throw new LoginErrorxception("请先登录");
        }
    }

    @Override
    public Mine mineShow(String phone) {
//        参与校验
        if (phone==null){
            throw new PasswordException("查看个人信息的手机号为空！");
        }
     User user=userMapper.selectPhone(phone);
//        查询校验
        if (user==null){
            throw new SelectExcepion("用户不存在！");
        }
//    用户是否开通会员
        if (user.getIsVip()==1){
//            查出会员类型
            Member member=memberMapper.selectMemberUserOneId(user.getMemberId());
//           查询校验
            if (member==null){
                throw new SelectExcepion("查出的会员参数没空！");
            }
//            计算年龄
            Date nowTime= new Date();
            Instant instant1=user.getBirthday().toInstant();
            Instant instant2=nowTime.toInstant();
            Duration duration=Duration.between(instant1,instant2);
            SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
            String birthdaystr=format.format(user.getBirthday());
            if ((duration.toDays()/365)>user.getAge()){
                User user1=new User();
                user.setAge((int) (duration.toDays()/365));
                Integer result=userMapper.updateMine(user.getPhone(),user.getAge(),user.getNickname(),user.getPassword(),user.getGender(),user.getBirthday(),birthdaystr);
                if (result==null){
                    throw new UpdateException("年龄更新失败！");
                }
                System.out.println("年龄自动更新");
            }

//            封装数据
            Mine mine=new Mine(user.getId(),user.getPhone(),user.getAge(),user.getPassword(),user.getNickname(),user.getGender(),user.getBirthday(),user.getAvatar(),user.getWeight(),member.getIcon());
            return mine;
        }else {
            //            封装数据
            Mine mine=new Mine(user.getId(),user.getPhone(),user.getAge(),user.getPassword(),user.getNickname(),user.getGender(),user.getBirthday(),user.getAvatar(),user.getWeight(),null);
            return mine;
    }

    }

    @Override
    public void uploadAvatar(MultipartFile file,String phone) throws Exception  {
        if (file.isEmpty()){
            throw new FileEmptyException("文件上传异常！文件不能为空");
        }
        if (file.getSize()>AVATAR_MAX_SIZE){
            throw new FileSizeException("文件上传异常！文件大小超过上限:"+AVATAR_MAX_SIZE);
        }
        if (!AVATARTYPE.contains(file.getContentType())){
            throw new FileTypeException("文件上传异常！文件类型不正确，允许的类型有："+AVATARTYPE);
        }
        //生成文件名
        String ofilename=file.getOriginalFilename();
        Integer index=ofilename.lastIndexOf(".");
        String suffix="";
        if (index!=-1){
            suffix=ofilename.substring(index);
        }
        String filename= UUID.randomUUID().toString()+suffix;

        //生成目标路径
//        String filePath=request.getServletContext().getRealPath("upload");
        String filePath=LOCAL_UPLOAD_PATH;  //将它保存到本地计算机指定路径
        String filePath2=LOCAL_FRONT_PATH;
        File parent=new File(filePath);//备份服务器路径
        File parent2=new File(filePath2);//备份到前端
        if (!parent.exists()){
            parent.mkdirs();
        }
        if (!parent2.exists()){
            parent2.mkdirs();
        }
        //将用户上传的头像上传到服务器
//        File dest=new File(uploadDir,filename);
        File dest=new File(parent,filename);
//      由于没有服务器于是备到前端项目
        File dest2=new File(parent2,filename);

        try {
            file.transferTo(dest);
//            file.transferTo(dest2);
//            File localFile=new File(LOCAL_UPLOAD_PATH+filename);
            Files.copy(dest.toPath(),dest2.toPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
//        备份到前端
//        try {
//           ImagesUtils.copyImage(filePath+filename,filePath2+filename);
//            System.out.println("图片复制成功");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        String avatar="http://10.102.228.179:5173/static/avatar/user/"+filename; //存入服务器的路径，当前没有服务器，暂时改为本计算机的本项目路径做测试
//        将文件路径存入数据库
        Integer result=userMapper.updateAvatarToPhone(phone,avatar);
        if (result!=1){
            throw new UpdateException("头像更新失败！");
        }
        System.out.println("用户："+phone+"图片"+avatar+"上传成功！");
    }

    @Override
    public String downloadImages(String filePath) {
//        参数校验
        if (filePath == null) {
            throw new ParameterIsEmptyException("参数为空");
        }
// 创建一个文件对象，表示要读取的图片文件
        File imageFile = new File(filePath);
        if (imageFile==null){
            throw new FileEmptyException("文件路径为空！");
        }

        // 使用FileInputStream读取文件内容
        try (FileInputStream fileInputStream = new FileInputStream(imageFile)) {
            // 创建一个字节数组，用于存储文件的字节数据
            byte[] imageBytes = new byte[(int) imageFile.length()];

            // 将文件内容读取到字节数组中
            fileInputStream.read(imageBytes);

            // 使用Base64编码器将字节数组转换为Base64字符串
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            System.out.println("成功将图片"+filePath+"下载返回成功！");
            // 返回Base64编码的字符串
            return base64Image;

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void updateMine(User user,String newPassword,String confirmPassword) {
        if (user==null){
            throw new ParameterIsEmptyException("参数为空！");
        }
        if (user.getPhone()==null){
            throw new ParameterIsEmptyException("手机号为空！");
        }
//        查询数据库
        User selectUser=userMapper.selectPhone(user.getPhone());
        if (selectUser==null){
            throw new SelectExcepion("用户信息不存在！");
        }
//        判断需要更新的数据
        if (user.getNickname().equals(selectUser.getNickname())){
            user.setNickname(null);
        }
        if (user.getGender()==selectUser.getGender()){
            user.setGender(null);
        }
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String birthdayOld=dateFormat.format(selectUser.getBirthday());
        String birthdayNew=dateFormat.format(user.getBirthday());
        System.out.println("更新的日期字符串为："+birthdayNew);
        if (birthdayNew.equals(birthdayOld)){
            user.setBirthday(null);
            user.setAge(null);
            birthdayNew=null;
        }else {
            //   计算年龄
            Date nowTime= new Date();
            Instant instant1=user.getBirthday().toInstant();
            Instant instant2=nowTime.toInstant();
            Duration duration=Duration.between(instant1,instant2);
            Integer age=(int)duration.toDays()/365;
            if (age<1){
                user.setAge(1);
            }else {
                user.setAge(age);
            }
        }
//      判断密码是否更新
        if (user.getPassword()!=null&&newPassword!=null&&confirmPassword!=null){
//           原密码不一致
            user.setPassword(MD5AndSalt.getMD5Password(user.getPassword(),selectUser.getSalt()));
           if (!user.getPassword().equals(selectUser.getPassword())){
               throw new OldPasswordErrorException("原密码不正确！");
           }
//           新密码和确认密码是否一致
            if (!newPassword.equals(confirmPassword)){
                throw new PasswordInconsistencyException("新密码和确认密码不一致！");
            }
//            将原来密码替换成新密码
            user.setPassword(MD5AndSalt.getMD5Password(newPassword,selectUser.getSalt()));
        }else {
            user.setPassword(null);
        }
        System.out.println("更新的个人性别："+user.getGender());
//        更新个人数据
        Integer result=userMapper.updateMine(user.getPhone(),user.getAge(),user.getNickname(),user.getPassword(),user.getGender(),user.getBirthday(),birthdayNew);
        if (result!=1){
            throw new UpdateException("更新个人信息失败！");
        }
        System.out.println("用户更新个人数据成功："+user.getPhone());

    }

    @Override
    public void logout(String phone) {
//        参数校验
         if (phone==null){
             throw  new ParameterIsEmptyException("参数为空");
         }
//         删除redis中会话信息
           RedisUtils.deleteKeyValue("phone:"+phone);
           RedisUtils.deleteKeyValue("password:"+phone);
           RedisUtils.deleteKeyValue("time:"+phone);
        System.out.println("用户："+phone+"成功注销账户退出系统");
    }


}
